package org.jeecg.modules.fk.service;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.modules.fk.mapper.auto.model.*;
import org.jeecg.modules.fk.vo.RiskResultVO;
import org.jeecg.modules.fk.vo.indicator.IndicatorDefineVO;
import org.jeecg.modules.fk.vo.indicator.IndicatorStatisticVO;
import org.jeecg.modules.fk.mapper.manual.model.RiskFpFpqkExt;
import org.jeecg.modules.fk.mapper.manual.model.RiskZzsxgmSbqkExt;
import org.jeecg.modules.fk.constant.ReportStatusEnum;
import org.jeecg.modules.fk.constant.ZbTypeEnum;
import org.jeecg.modules.fk.vo.inner.req.GetLastRiskRecordReqDTO;
import org.jeecg.modules.fk.vo.inner.req.GetLastRiskReportReqDTO;
import org.jeecg.modules.fk.vo.inner.req.GetLocalRiskRecordReqDTO;
import org.jeecg.modules.fk.vo.inner.req.GetPastRiskReportReqDTO;
import org.jeecg.modules.fk.vo.inner.resp.*;
import org.jeecg.modules.fk.vo.req.*;
import org.jeecg.modules.fk.vo.req.bszs.FkReportRcreateHisDTO;
import org.jeecg.modules.fk.vo.req.bszs.QueryFkReportRcreateHisDTO;
import org.jeecg.modules.fk.vo.resp.FxmxRespDTO;
import org.jeecg.modules.fk.vo.resp.PastRiskReportRespDTO;
import org.jeecg.modules.fk.vo.resp.RiskReportRespDTO;
import org.jeecg.modules.fk.vo.fxmx.FxmxFlVO;
import org.jeecg.modules.fk.vo.fxmx.FxmxVO;
import org.jeecg.modules.fk.vo.fxmx.JieLunVo;
import org.jeecg.modules.fk.properties.TaxProperties;
import org.jeecg.modules.fk.repository.FkDaoRepository;
import org.jeecg.modules.fk.service.call.FkBszsApiBaseCall;
import org.jeecg.modules.fk.service.call.FkReportRcreateHisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;

@Slf4j
@Service
public class FxmxService {

    @Autowired
    private FkDaoRepository daoRepository;
    @Autowired
    private RiskIndicatorService riskIndicatorService;
    @Autowired
    private RiskResultService riskResultService;
    @Autowired
    private FkReportRcreateHisService fkReportRcreateHisService;
    @Resource
    private TaxProperties bszsProperties;

    @Autowired
    private FkBszsApiBaseCall fkBszsApiBaseCall;

    /**
     * 根据纳税人识别号 查询 指标风险
     *
     * @param nsrsbh 纳税人识别号
     * @param skssqq 税款所属期起
     * @param skssqz 税款所属期止
     */
    private List<FxmxFlVO> zbFxByNsrsbh(ZbTypeEnum zbType, String nsrsbh, String skssqq, String skssqz, String agentId) {
        //获取风险结果
        Map<String, RiskResultVO> riskResultMap = this.riskResultService.getriskResultMap(zbType, nsrsbh, skssqq, skssqz);

        List<IndicatorStatisticVO> defineGroupList = this.riskIndicatorService.getDefineGroup(zbType);

        //组装结果
        return defineGroupList.stream()
                .map(e -> {
                    FxmxFlVO fxmxFlVO = new FxmxFlVO();
                    BeanUtils.copyProperties(e, fxmxFlVO);

                    List<IndicatorDefineVO> defineList = e.getDefineList();
                    fxmxFlVO.setYwxlSl(defineList.size());

                    List<FxmxVO> fxydList = defineList.stream()
                            .filter(k -> { //过滤没有疑点的数据
                                RiskResultVO riskResultVO = riskResultMap.get(k.getZbbh());
                                return riskResultVO != null;
                            })
                            .map(k -> {
                                //指标结果
                                RiskResultVO riskResultVO = riskResultMap.get(k.getZbbh());

                                FxmxVO fxmxVO = new FxmxVO();
                                BeanUtils.copyProperties(k, fxmxVO);
                                fxmxVO.setZycd(riskResultVO.getZycd());
                                fxmxVO.setZbResult(riskResultVO.getZbResult().replaceAll("(\\d)(?=(\\d{3})+\\.)", "$1,"));
                                fxmxVO.setYdjy(riskResultVO.getYdjy());
                                //中介是否有指标风险自定义应对措施，有用定义的
                                if (null != agentId) {
                                    String ydjy = this.daoRepository.getRiskZbAdviseExtMapper().getAgentZbAdvise(agentId, nsrsbh, skssqq, skssqz, k.getZbbh());
                                    if (null != ydjy) {
                                        fxmxVO.setYdjy(ydjy);
                                    }
                                }

                                fxmxVO.setFormula(riskResultVO.getFormula());
                                fxmxVO.setZbJson(riskResultVO.getZbJson());

                                return fxmxVO;
                            })
                            .collect(toList());

                    fxmxFlVO.setYdSl(fxydList.size());
                    fxmxFlVO.setFxmx(fxydList);
                    return fxmxFlVO;
                })
                .collect(toList());
    }

    public FxmxFlByNsrsbhRespDTO getFxmxByNsrsbh(ZbTypeEnum zbType, String nsrsbh, String skssqq, String skssqz) {
        FxmxFlByNsrsbhRespDTO result = new FxmxFlByNsrsbhRespDTO();

        //风险类别
        List<FxmxFlVO> list = this.zbFxByNsrsbh(zbType, nsrsbh, skssqq, skssqz, null);
        result.setFxmxFl(JSONArray.toJSONString(list));

        // 结论、测检得分
        RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(zbType.toString(), nsrsbh, skssqq, skssqz);

        if (null != risk) {
            result.setScore(String.valueOf(risk.getDfxj()));

            JieLunVo jieLun = new JieLunVo();
            BeanUtils.copyProperties(risk, jieLun);
            result.setJieLun(JSONObject.toJSONString(jieLun));
            result.setBgdj(risk.getBgdj());
        }

        return result;
    }

    public RiskProcessListRespDTO getRiskProcessRecord(GetLocalRiskRecordReqDTO dto) {
        RiskProcessListRespDTO result = new RiskProcessListRespDTO();

        List<RiskProcessList> rsikProcess = this.daoRepository.getRiskProcessListExtMapper().getRiskProcessRecord(dto.getYwdlDm(), dto.getNsrsbh(), dto.getSkssqqs(), dto.getSkssqzs());

        result.setRsikProcess(rsikProcess);
        return result;
    }

    public LastRiskProcessRespDTO getLastRiskProcessRecord(GetLastRiskRecordReqDTO dto) {
        LastRiskProcessRespDTO result = new LastRiskProcessRespDTO();

        RiskProcessList rsikProcess = this.daoRepository.getRiskProcessListExtMapper().getLastRiskProcessRecord(dto.getYwdlDm(), dto.getNsrsbh(), dto.getSkssqq(), dto.getSkssqz());

        result.setLastRsikProcess(rsikProcess);
        return result;
    }

    public FxmxRespDTO getFxmx(ZbTypeEnum zbType, String nsrsbh, String skssqq, String skssqz, String agentId) {
        FxmxRespDTO result = new FxmxRespDTO();

        //风险类别
        List<FxmxFlVO> list = this.zbFxByNsrsbh(zbType, nsrsbh, skssqq, skssqz, agentId);
        result.setFxmxFl(list);

        // 结论、测检得分
        RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(zbType.toString(), nsrsbh, skssqq, skssqz);

        if (null != risk) {
            result.setScore(String.valueOf(risk.getDfxj()));

            JieLunVo jieLun = new JieLunVo();
            BeanUtils.copyProperties(risk, jieLun);
            result.setJieLun(jieLun);
            result.setBgdj(risk.getBgdj());
        } else {
            //空报告，造假数据
            JieLunVo jieLun = new JieLunVo();
            result.setJieLun(jieLun);
        }

        return result;
    }

    /**
     * 完善风控期别日期数据
     *
     * @param reportTimes
     */
    protected FpSkssqListDTO improveRiskQbPraramData(List<String> reportTimes) {
        FpSkssqListDTO fpSkssqList = new FpSkssqListDTO();
        List<String> skssqqs = new ArrayList<>();
        List<String> skssqzs = new ArrayList<>();

        for (String reportTime : reportTimes) {
            DateTime reportTimeDate = DateUtil.parse(reportTime, "yyyy-MM"); //报告年月

            String sssqQ = DateUtil.format(DateUtil.beginOfMonth(reportTimeDate), DatePattern.NORM_DATE_PATTERN);//税款所属期起,yyyy-MM-dd,月第一天，2018-01-01; //税款所属期起,yyyy-MM-dd
            String sssqZ = DateUtil.format(DateUtil.endOfMonth(reportTimeDate), DatePattern.NORM_DATE_PATTERN);//税款所属期止,yyyy-MM-dd,月末，2018-01-31; //税款所属期止,yyyy-MM-dd
            skssqqs.add(sssqQ);
            skssqzs.add(sssqZ);
        }

        fpSkssqList.setSkssqqs(skssqqs);
        fpSkssqList.setSkssqzs(skssqzs);
        return fpSkssqList;
    }

    public PastRiskReportRespDTO getPastRiskReport(GetPastRiskReportReqDTO reqDto) {
        PastRiskReportRespDTO data = new PastRiskReportRespDTO();
        List<RiskReportRespDTO> fpfxbg = new ArrayList<>();
        List<String> queryReportTimeList = reqDto.getReportTimeList();

        //  1、获取本地生成时间
        FpSkssqListDTO fpSkssqList = improveRiskQbPraramData(reqDto.getReportTimeList());
        List<RiskProcessList> riskProcessList = this.daoRepository.getRiskProcessListExtMapper().getRiskProcessRecord(reqDto.getType().toString(), reqDto.getNsrsbh(), fpSkssqList.getSkssqqs(), fpSkssqList.getSkssqzs());

        Map<String, RiskProcessList> mapRiskProcess = new HashMap<>();
        if (null != riskProcessList && riskProcessList.size() > 0) {
            mapRiskProcess = riskProcessList.stream().collect(toMap(y -> DateUtil.format(y.getSkssqq(), "yyyy-MM"), x -> x));
        }

        // 2、获取重新生成时间
        List<QueryFkReportRcreateHisDTO> queryDTOList = improveRiskUpdatePraramData(reqDto.getType().toString(), reqDto.getNsrsbh(), queryReportTimeList);
        Map<String, FkReportRcreateHisDTO> mapHis = new HashMap<>();
        List<FkReportRcreateHisDTO> resultHis = fkReportRcreateHisService.listFkReportRcreateHis(queryDTOList);
        if (null != resultHis && resultHis.size() > 0) {
            mapHis = resultHis.stream().collect(toMap(y -> DateUtil.format(y.getSkssqq(), "yyyy-MM"), x -> x));
        }

        // 本地成生记录--没有，同时重新生成时间也没有，--未生成
        if ((riskProcessList == null || riskProcessList.size() == 0) && ((resultHis == null || resultHis.size() == 0))) {
            List<RiskReportRespDTO> fpfxReports = new ArrayList<>();
            // 未生成
            for (String reportTime : queryReportTimeList) {
                RiskReportRespDTO fpRiskReport = new RiskReportRespDTO();
                fpRiskReport.setReportState(ReportStatusEnum.NOT_GENERATED);

                fpRiskReport.setReportTime(reportTime);

                fpfxReports.add(fpRiskReport);
            }
            data.setData(fpfxReports);
            return data;
        }

        for (String reportTime : queryReportTimeList) {
            FkReportRcreateHisDTO his = mapHis.get(reportTime);
            RiskProcessList riskProcess = mapRiskProcess.get(reportTime);

            RiskReportRespDTO fpRiskReport = null;

            /* 一、已生成
             * 1 有本地记录，没有重新生成时间 --已生成
             * 2 本地时间大于重新生成时间 --已生成
             * */
            if ((riskProcess != null && his == null) || (riskProcess != null && his != null && riskProcess.getUpdateDate().after(his.getUpdateTime()))) {
                // 已生成
                fpRiskReport = getRiskReport(reqDto.getType(), reqDto.getNsrsbh(), reportTime);
            } else if ((riskProcess == null && his != null) || (riskProcess != null && his != null && riskProcess.getUpdateDate().before(his.getUpdateTime()))) {
                /* 二、 生成中
                 *  1 没有本地记录，有重新生成时间 --生成中
                 *  2 本地时间小于重新生成时间 --生成中
                 * */
                //把生成中加到最后集合
                fpRiskReport = new RiskReportRespDTO();
                fpRiskReport.setReportTime(reportTime);
                fpRiskReport.setReportState(ReportStatusEnum.IN_GENERATED);
            } else {
                //未生成
                fpRiskReport = new RiskReportRespDTO();
                fpRiskReport.setReportTime(reportTime);
                fpRiskReport.setReportState(ReportStatusEnum.NOT_GENERATED);
            }

            fpfxbg.add(fpRiskReport);
        }

        data.setData(fpfxbg);
        return data;
    }

    protected List<QueryFkReportRcreateHisDTO> improveRiskUpdatePraramData(String ywdlDm, String nsrsbh, List<String> reportTimes) {
        List<QueryFkReportRcreateHisDTO> queryDTOList = new ArrayList<>();

        for (String reportTime : reportTimes) {
            QueryFkReportRcreateHisDTO his = new QueryFkReportRcreateHisDTO();
            his.setYwdlDm(ywdlDm);
            his.setNsrsbh(nsrsbh);

            DateTime reportTimeDate = DateUtil.parse(reportTime, "yyyy-MM"); //报告年月

            String sssqQ = DateUtil.format(DateUtil.beginOfMonth(reportTimeDate), DatePattern.NORM_DATE_PATTERN);//税款所属期起,yyyy-MM-dd,月第一天，2018-01-01
            String sssqZ = DateUtil.format(DateUtil.endOfMonth(reportTimeDate), DatePattern.NORM_DATE_PATTERN);//税款所属期止,yyyy-MM-dd,月末，2018-01-31
            his.setSkssqq(sssqQ);
            his.setSkssqz(sssqZ);

            queryDTOList.add(his);
        }

        return queryDTOList;
    }

    public RiskReportRespDTO getRiskReport(ZbTypeEnum zbType, String nsrsbh, String reportTime) {
        RiskReportRespDTO result = new RiskReportRespDTO();
        result.setReportTime(reportTime);

        DateTime reportTimeDate = DateUtil.parse(reportTime, "yyyy-MM"); //报告年月

        String skssqq = DateUtil.format(DateUtil.beginOfMonth(reportTimeDate), DatePattern.NORM_DATE_PATTERN);//税款所属期起,yyyy-MM-dd,月第一天，2018-01-01
        String skssqz = DateUtil.format(DateUtil.endOfMonth(reportTimeDate), DatePattern.NORM_DATE_PATTERN);//税款所属期止,yyyy-MM-dd,月末，2018-01-31

        //风险类别
        List<FxmxFlVO> list = this.zbFxByNsrsbh(zbType, nsrsbh, skssqq, skssqz, null);
        result.setFxmxFl(list);

        // 结论、测检得分
        RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(zbType.toString(), nsrsbh, skssqq, skssqz);

        if (null != risk) {
            result.setScore(String.valueOf(risk.getDfxj()));

            JieLunVo jieLun = new JieLunVo();
            BeanUtils.copyProperties(risk, jieLun);
            result.setJieLun(jieLun);
            result.setBgdj(risk.getBgdj());
            result.setCreateTime(risk.getCreateDate());//报告生成时间
            result.setReportState(ReportStatusEnum.GENERATED);
        } else {
            result.setReportState(ReportStatusEnum.IN_GENERATED);
        }

        return result;
    }

    public LastRiskReportTimeRespDTO getLastRiskReportTime(GetLastRiskReportReqDTO reqDto) {
        LastRiskReportTimeRespDTO lastRiskReportTimeRespDTO = new LastRiskReportTimeRespDTO();

        RiskProcessList riskProcessList = this.daoRepository.getRiskProcessListExtMapper().getLastSkssqRiskProcessRecord(reqDto.getYwdlDm(), reqDto.getNsrsbh());

        if (null != riskProcessList) {
            String skssqq = DateUtil.format(riskProcessList.getSkssqq(), "yyyy-MM-dd");
            String skssqz = DateUtil.format(riskProcessList.getSkssqz(), "yyyy-MM-dd");
            RiskProcessList lastRiskProcessList = this.daoRepository.getRiskProcessListExtMapper().getLastRiskProcessRecord(reqDto.getYwdlDm(), reqDto.getNsrsbh(), skssqq, skssqz);

            List<QueryFkReportRcreateHisDTO> queryDTOList = new ArrayList<>();

            QueryFkReportRcreateHisDTO his = new QueryFkReportRcreateHisDTO();
            his.setNsrsbh(reqDto.getNsrsbh());
            his.setYwdlDm(reqDto.getYwdlDm());
            his.setSkssqq(skssqq);
            his.setSkssqz(skssqz);

            queryDTOList.add(his);

            // 2、获取重新生成时间
            List<FkReportRcreateHisDTO> resultHis = fkReportRcreateHisService.listFkReportRcreateHis(queryDTOList);

            /* 已生成
             * 1 有本地记录，没有重新生成时间 --已生成
             * 2 本地时间大于重新生成时间 --已生成
             * */
            if ((lastRiskProcessList != null && (resultHis == null || resultHis.size() == 0)) || (lastRiskProcessList != null && resultHis != null && resultHis.size() > 0 && lastRiskProcessList.getUpdateDate().after(resultHis.get(0).getUpdateTime()))) {
                // 已生成
                lastRiskReportTimeRespDTO.setReportTime(lastRiskProcessList.getSkssqq());

                if (false == ObjectUtils.isEmpty(lastRiskProcessList.getSkssqq())) {
                    String formatSkssqq = DateUtil.format(lastRiskProcessList.getSkssqq(), "yyyy-MM-dd");
                    lastRiskReportTimeRespDTO.setSkssqq(formatSkssqq);
                }

                if (false == ObjectUtils.isEmpty(lastRiskProcessList.getSkssqz())) {
                    String formatSkssqz = DateUtil.format(lastRiskProcessList.getSkssqz(), "yyyy-MM-dd");
                    lastRiskReportTimeRespDTO.setSkssqz(formatSkssqz);
                }

                //获取结论
                RiskReportLevel risk = this.daoRepository.getRiskReportLevelExtMapper().getRiskReportLevelByKey(reqDto.getYwdlDm(), reqDto.getNsrsbh(), skssqq, skssqz);

                if (null != risk) {
                    JieLunVo jieLun = new JieLunVo();
                    BeanUtils.copyProperties(risk, jieLun);
                    lastRiskReportTimeRespDTO.setJieLun(JSONObject.toJSONString(jieLun));
                }
            }
        }

        return lastRiskReportTimeRespDTO;
    }

    public RiskZzsSbqk getRiskZzsSbqk(RiskZzsSbqkReqDTO dto) {
        return this.daoRepository.getRiskZzsSbqkExtMapper().selectByPrimaryKey(dto.getNsrsbh(), dto.getSkssqq(), dto.getSkssqz());
    }

    public RiskStandardZzsHySfl getRiskStandardZzsHySfl(RiskStandardZzsHySflKey dto) {
        String region = dto.getRegion();
        String zcdzxzqhszDm = dto.getZcdzxzqhszDm();
        // 无其它省份行业数据，用广东广州行业数据代替
        if (!"440000".equals(region)) {
            region = "440000";
            zcdzxzqhszDm = "4401";
        }

        // 暂时固定取2019年度的行业税负率
        Short year = dto.getNd();
        year = 2019;

        return this.daoRepository.getRiskStandardZzsHySflExtMapper()
                .selectByParam(year, region, dto.getHyDm(), zcdzxzqhszDm);
    }

    public void createZbAdvise(RiskZbAdvise dto) {
        //把相同中介、相同税期、相同指标的历史应对措施逻辑删除
        this.daoRepository.getRiskZbAdviseExtMapper().deleteHistoryZbAdvise(dto.getAgentId(), dto.getNsrsbh(), dto.getSkssqq(), dto.getSkssqz(), dto.getZbbh(), new Date());

        //新增应对措施
        dto.setCreateTime(new Date());
        this.daoRepository.getRiskZbAdviseMapper().insertSelective(dto);
    }

    public RiskStandardSdsHySfl getRiskStandardSdsHySfl(RiskStandardSdsHySflKey dto) {
        String region = dto.getRegion();
        if (!"440000".equals(region)) {
            dto.setRegion("440000");
            dto.setZcdzxzqhszDm("4401");
        }

        // 暂时固定取2019年度的行业税负率
        short year = 2019;
        dto.setNd(year);

        return this.daoRepository.getRiskStandardSdsHySflMapper().selectByPrimaryKey(dto);
    }

    public RiskStandardSdsHyMll getRiskStandardSdsHyMll(RiskStandardSdsHyMllKey dto) {
        String region = dto.getRegion();
        if (!"440000".equals(region)) {
            dto.setRegion("440000");
            dto.setZcdzxzqhszDm("4401");
        }

        // 暂时固定取2019年度的行业毛利率
        short year = 2019;
        dto.setNd(year);

        return this.daoRepository.getRiskStandardSdsHyMllMapper().selectByPrimaryKey(dto);
    }

    public RiskQysdsSbqk getRiskQysdsSbqk(RiskQysdsSbqkKey dto) {
        return this.daoRepository.getRiskQysdsSbqkMapper().selectByPrimaryKey(dto);
    }

    public String getSbsj(SbsjDTO dto) {
        return this.fkBszsApiBaseCall.postJsonParamReturnOneLevelCall(false,
                "申报数据",
                null,
                bszsProperties.getSbSdsUrl(),
                null,
                dto);
    }

    /**
     * 获取增值税小规模缴纳情况
     *
     * @param dto 增值税小规模缴纳请求DTO对象
     *
     * @return 增值税小规模缴纳响应DTO对象
     */
    public RiskZzsxgmSbqkRespDTO getRiskZzsxgmSbqk(RiskZzsxgmSbqkReqDTO dto) {
        String nsrsbh = dto.getNsrsbh();
        String skssqq = dto.getSkssqq();
        String skssqz = dto.getSkssqz();
        String agentId = dto.getAgentId();
        String cycleformat = "YYYYQQ";

        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        try {
            YearMonth ymSkssqq = YearMonth.parse(skssqq, fmt);
            YearMonth ymSkssqz = YearMonth.parse(skssqz, fmt);

            long months = Math.abs(ChronoUnit.MONTHS.between(ymSkssqq, ymSkssqz));
            // last 12 months
            if (0L == months) {
                ymSkssqq = ymSkssqq.minusMonths(11);
                cycleformat = "YYYYMM";
            }

            // last 4 quarters
            if (2L == months) {
                ymSkssqq = ymSkssqq.minusMonths(9);
                cycleformat = "YYYYQQ";
            }

//            if (11L == months) {
//                ymSkssqq = ymSkssqq.minusMonths(12);
//            }

            skssqq = ymSkssqq.atDay(1).format(fmt);
        } catch (Exception e) {
            log.error("====>>>>转换所属期失败, skssqq:{}, skssqz:{}, cycleformat:{}, Exception:{}", skssqq, skssqz, cycleformat, e);
        }

        List<RiskZzsxgmSbqkExt> riskZzsxgmSbqkExtList = this.daoRepository.getRiskZzsxgmSbqkExtMapper().getRiskZzsxgmSbqk(nsrsbh, skssqq, skssqz, cycleformat);

        RiskZzsxgmSbqkRespDTO riskZzsxgmSbqkRespDTO = new RiskZzsxgmSbqkRespDTO();
        riskZzsxgmSbqkRespDTO.setRiskZzsxgmSbqkList(riskZzsxgmSbqkExtList);

        skssqq = dto.getSkssqq();
        String zbbhPrefix = "ZZS08";
//        List<FxmxFlVO> fxmxFlVOList = this.zbFxByNsrsbh(ZbTypeEnum.ZZS, nsrsbh, skssqq, skssqz, agentId);
//        fxmxFlVOList = fxmxFlVOList.stream()
//                .filter(f -> !ObjectUtils.isEmpty(f.getYwxlDm()) &&
//                        zbbhPrefix.equals(f.getYwxlDm()))
//                .collect(toList());
//
//        riskZzsxgmSbqkRespDTO.setFxmxFl(fxmxFlVOList);

        List<FxmxVO> zbFxList = this.getZbFx(ZbTypeEnum.ZZS, zbbhPrefix, nsrsbh, skssqq, skssqz, agentId);
        riskZzsxgmSbqkRespDTO.setFxmx(zbFxList);

        return riskZzsxgmSbqkRespDTO;
    }

    /**
     * 查询指标风险
     *
     * @param zbType     指标类型
     * @param zbbhPrefix 指标编号前缀
     * @param nsrsbh     纳税人识别号
     * @param skssqq     税款所属期起
     * @param skssqz     税款所属期止
     * @param agentId    中介ID
     *
     * @return
     */
    private List<FxmxVO> getZbFx(ZbTypeEnum zbType, String zbbhPrefix, String nsrsbh, String skssqq, String skssqz, String agentId) {
        //获取风险结果
        Map<String, RiskResultVO> riskResultMap = this.riskResultService.getriskResultMap(zbType, nsrsbh, skssqq, skssqz);

        List<RiskIndicatorDefineWithBLOBs> indicatorDefineListByZbbhPrefixList = this.daoRepository.getRiskIndicatorExtMapper().getIndicatorDefineListByZbbhPrefix(zbbhPrefix);

        List<FxmxVO> fxydList = indicatorDefineListByZbbhPrefixList.stream()
//                .filter(k -> riskResultMap.containsKey(k.getZbbh()))
                .map(k -> {
                    //指标结果
                    RiskResultVO riskResultVO = riskResultMap.get(k.getZbbh());

                    FxmxVO fxmxVO = new FxmxVO();
                    BeanUtils.copyProperties(k, fxmxVO);
                    fxmxVO.setYdSl(Integer.valueOf(0));
                    fxmxVO.setIsPassed(Boolean.TRUE);

                    if (!ObjectUtils.isEmpty(riskResultVO)) {
                        fxmxVO.setZycd(riskResultVO.getZycd());
                        fxmxVO.setZbResult(riskResultVO.getZbResult().replaceAll("(\\d)(?=(\\d{3})+\\.)", "$1,"));
                        fxmxVO.setYdjy(riskResultVO.getYdjy());
                        fxmxVO.setFormula(riskResultVO.getFormula());
                        fxmxVO.setZbJson(riskResultVO.getZbJson());
                        fxmxVO.setYdSl(Integer.valueOf(1));
                        fxmxVO.setIsPassed(Boolean.FALSE);
                    }

                    //中介是否有指标风险自定义应对措施，有用定义的
                    if (null != agentId) {
                        String ydjy = this.daoRepository.getRiskZbAdviseExtMapper().getAgentZbAdvise(agentId, nsrsbh, skssqq, skssqz, k.getZbbh());
                        if (null != ydjy) {
                            fxmxVO.setYdjy(ydjy);
                        }
                    }

                    return fxmxVO;
                })
                .collect(toList());

        return fxydList;
    }

    /**
     * 获取小规模纳税人发票情况
     *
     * @param dto 小规模纳税人发票情况请求DTO对象
     *
     * @return 小规模纳税人发票情况响应DTO对象
     */
    public RiskFpxgmFpqkRespDTO getRiskFpxgmFpqk(RiskFpxgmFpqkReqDto dto) {
        String nsrsbh = dto.getNsrsbh();
        String skssqq = dto.getSkssqq();
        String skssqz = dto.getSkssqz();
        String agentId = dto.getAgentId();
        String cycleformat = "YYYYQQ";

        List<String> fplxDmList = dto.getFplxDmList();
        if (true == ObjectUtils.isEmpty(fplxDmList)) {
            fplxDmList = Arrays.asList("01", "02");
        }

        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        try {
            YearMonth ymSkssqq = YearMonth.parse(skssqq, fmt);
            YearMonth ymSkssqz = YearMonth.parse(skssqz, fmt);

            long months = Math.abs(ChronoUnit.MONTHS.between(ymSkssqq, ymSkssqz));
            // last 6 months
            if (0L == months) {
                ymSkssqq = ymSkssqq.minusMonths(5);
                cycleformat = "YYYYMM";
            }

            // last 4 quarters
            if (2L == months) {
                ymSkssqq = ymSkssqq.minusMonths(9);
                cycleformat = "YYYYQQ";
            }

//            if (11L == months) {
//                ymSkssqq = ymSkssqq.minusMonths(12);
//            }

            skssqq = ymSkssqq.atDay(1).format(fmt);
        } catch (Exception e) {
            log.error("====>>>>转换所属期失败, skssqq:{}, skssqz:{}, cycleformat:{}, Exception:{}", skssqq, skssqz, cycleformat, e);
        }

        List<RiskFpFpqkExt> riskFpFpqkExtList = this.daoRepository.getRiskFpFpqkExtMapper().getRiskFpxgmFpqk(nsrsbh, skssqq, skssqz, fplxDmList, cycleformat);

        RiskFpxgmFpqkRespDTO riskFpxgmFpqkRespDTO = new RiskFpxgmFpqkRespDTO();
        riskFpxgmFpqkRespDTO.setRiskFpFpqkExtList(riskFpFpqkExtList);

        skssqq = dto.getSkssqq();
        String zbbhPrefix = "ZZSFP06";
//        List<FxmxFlVO> fxmxFlVOList = this.zbFxByNsrsbh(ZbTypeEnum.ZZS, nsrsbh, skssqq, skssqz, agentId);
//        fxmxFlVOList = fxmxFlVOList.stream()
//                .filter(f -> !ObjectUtils.isEmpty(f.getYwxlDm()) &&
//                        zbbhPrefix.equals(f.getYwxlDm()))
//                .collect(toList());
//
//        riskFpxgmFpqkRespDTO.setFxmxFl(fxmxFlVOList);

        List<FxmxVO> zbFxList = this.getZbFx(ZbTypeEnum.ZZSFP, zbbhPrefix, nsrsbh, skssqq, skssqz, agentId);
        riskFpxgmFpqkRespDTO.setFxmx(zbFxList);

        return riskFpxgmFpqkRespDTO;
    }

}
